package com.example.jsoncomponent;

import cn.hutool.core.util.NumberUtil;
import com.example.dto.UserDTO;
import com.example.util.DateUtil;
import com.fasterxml.jackson.core.JacksonException;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.ObjectCodec;
import com.fasterxml.jackson.databind.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.jackson.JsonComponent;

import java.io.IOException;
import java.util.Objects;

/**
 * @Author: 自定义序列化器和反序列化器
 * @Description: 用户信息json序列化
 * @Date: 2025/8/19 上午10:42
 * @Version: 1.0
 */
@Slf4j
@JsonComponent
public class UserJsonComponent {

    /**
     * 自定义序列化器
     */
    public static class Serializer extends JsonSerializer<UserDTO> {

        /**
         * 1、一次查不出完整的数据返回给客户端，需要根据需求做一些个性化的调整
         * 2、根据不同的权限给前端返回不同的序列化数据
         * @param userDTO
         * @param jsonGen
         * @param serializerProvider
         * @throws IOException
         */
        @Override
        public void serialize(UserDTO userDTO, JsonGenerator jsonGen, SerializerProvider serializerProvider) throws IOException {
            // 开始序列化 - springBoot 3以上需要声明，没有则异常告警
            jsonGen.writeStartObject();
            // writeFieldName , writeObject 成对依次设置值，并且先配置字段再设置值，
            // 否则，如果当前没有有效的自定义序列化，则异常告警，有也是显示不完整的json数据
            jsonGen.writeFieldName("id");
            jsonGen.writeObject(userDTO.getId());
            jsonGen.writeFieldName("timeDate");
            jsonGen.writeObject(userDTO.getTimeDate());
            // 目前有的设置的字段，则前面设置的会被覆盖
            jsonGen.writeNumberField("id", userDTO.getId());
            jsonGen.writeStringField("user_name", userDTO.getUserName());
            jsonGen.writeObjectField("cn_name", userDTO.getCName());
            // 结束提交序列化
            jsonGen.writeEndObject();
        }
    }

    /**
     * 自定义反序列化器
     */
    public static class Deserializer extends JsonDeserializer<UserDTO> {

        @Override
        public UserDTO deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException {
            ObjectCodec codec = jsonParser.getCodec();
            JsonNode jsonNode = codec.readTree(jsonParser);
            log.info("自定义反序列化器 jsonNode:{}",jsonNode);
            UserDTO userDTO = new UserDTO();
            JsonNode id = jsonNode.get("id");
            if (Objects.nonNull(id) && NumberUtil.isInteger(String.valueOf(id))) {
                userDTO.setId(id.intValue());
            }
            JsonNode userName = jsonNode.get("user_name");
            if (Objects.nonNull(userName)) {
                userDTO.setUserName(userName.textValue());
            }
            JsonNode cName = jsonNode.get("cn_name");
            if (Objects.nonNull(cName)) {
                userDTO.setCName(cName.textValue());
            }
            JsonNode timeDate = jsonNode.get("timeDate");
            if (Objects.nonNull(timeDate)) {
                userDTO.setTimeDate(DateUtil.stringToDate(timeDate.textValue(), DateUtil.YYYY_MM_DD_HH_MM_SS));
            }
            return userDTO;
        }
    }

}
